#ifndef __SIMPLE_BLDCMOTOR_H__
#define __SIMPLE_BLDCMOTOR_H__

#ifndef __BLDCMOTOR_H__
#define __BLDCMOTOR_H__

#include "plat/nonecopyable.h"
#include "device/softpointpwm.h"
#include "soc/soc_gpio.h"
#include "device_def.h"
#include "spwm.h"

/// @brief BLDC 驱动
/// @param
///      典型参数:
///      调制波20KHZ  载波 50HZ
///      更新周期: 20000/360 = 55.5  周期放慢1倍 111us， 角度每次增加2度
class Simple_BLDC_Motor : public NoneCopyable
{
public:
    enum class MotorControlState
    {
        Idle = 0,
        SpeedUp,
        SpeedMax,
        SpeedDown,
        SpeedLow,
    };

    enum class SpwmSpeedMode
    {
        Angle = 0,
        Index
    };

public:
    explicit Simple_BLDC_Motor();
    virtual ~Simple_BLDC_Motor();

public:
    void Config(SOC_Timer *timera, int cha,
                SOC_Timer *timerb, int chb,
                SOC_Timer *timerc, int chc,
                int coilPair,
                float ma,
                SpwmSpeedMode mode = SpwmSpeedMode::Angle);

    void ConfigSpeedAngle(float speedV0, float speedMax, float acc, int ms);
    void ConfigSpeedIndex(int speedIndex);

    //移动的角度, +-, 
    void MoveAngle(float angle);
    //移动到指定角度。
    //由于是开环，所以不一定电机到了实际角度，只是spwm到达相应的角度了
    void MoveAngleTo(float angle);
    
    //移动的索引
    void MoveIndex(int index);
    //移动的索引
    void MoveIndexTo(int index);

    bool IsMoving();
    void WaitMoveOver();

    void Start();
    void Pause();
    /// @brief 停止后，会释放力矩
    void Stop();

    SPwm &GetSpwmA();
    SPwm &GetSpwmB();
    SPwm &GetSpwmC();

public:
    //调速, 为了节约定时器，外部调用
    //1ms调用
    void Update();

private:
    //角度
    void SetAngle(float angle);
    //设置索引
    void SetIndex(int index);

    void UpdateAngle();
    void UpdateIndex();

    void MoveInit();

    void SpeedControl();

private:
    SPwm m_spwma;
    SPwm m_spwmb;
    SPwm m_spwmc;

    int m_coilPair = 7;
    SpwmSpeedMode m_speedMode = SpwmSpeedMode::Angle;

    MotorControlState m_controlState = MotorControlState::Idle;
    //角度
    float m_currentAngle = 0;
    float m_dstAngle = 0;

    float m_speedV0 = 0.1;//0.04;   //初始速度 angle/s 
    float m_speedAcc = 0.4;    //加速度  angle/s 
    float m_speedMax = 0.2;    //最大速度 angle/s 
    float m_speedUpTotalAngle = 0; //加速阶段需要的角度
    int m_speedUpMs = 100; //加速需要的ms
    float m_accAnglePerUs = 0; //没微妙的加速度
    
    float m_currentSpeedAngle = 0; //当前速度 
    
    //index
    int m_currentIndex = 0;
    int m_dstIndex = 0;
    int m_speedIndex = 1;

    //st
    bool m_isMoving = false;
    bool m_isPause = false;
};

#endif // __BLDCMOTOR_H__


#endif // __SIMPLE_BLDCMOTOR_H__
